package zhh.tangbao.commodity.serivce.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import zhh.tangbao.commodity.dao.CommodityMachineEntityDao;
import zhh.tangbao.commodity.dao.CommodityMachineStockDao;
import zhh.tangbao.commodity.dao.CommodityMachineStockDataDao;
import zhh.tangbao.commodity.dto.MachineQueryDto;
import zhh.tangbao.commodity.dto.MachineStockQueryDto;
import zhh.tangbao.commodity.entity.CommodityMachineEntity;
import zhh.tangbao.commodity.entity.CommodityMachineStock;
import zhh.tangbao.commodity.entity.CommodityMachineStockData;
import zhh.tangbao.commodity.manager.OrderPickUpManager;
import zhh.tangbao.commodity.serivce.CommodityMachineService;
import zhh.tangbao.commodity.vo.CommodityMachineStockVo;
import zhh.tangbao.commodity.vo.MachineOptionsVo;
import zhh.tangbao.commodity.vo.StockDataVo;
import zhh.tangbao.commodity.vo.StockVo;
import zhh.tangbao.system.constant.DataStatus;
import zhh.tangbao.system.utils.EncryptUtil;
import zhh.tangbao.system.utils.UserHolderUtil;
import zhh.tangbao.system.utils.ZhhStringUtil;

import java.util.Date;
import java.util.List;

/**
 * <p>
 *     描述
 * </p>
 * @author 粥灰灰
 * <p>2023/3/2</p>
 */

@Service
public class CommodityMachineServiceImpl implements CommodityMachineService {

    @Autowired
    private CommodityMachineEntityDao dao;

    @Autowired
    private CommodityMachineStockDao stockDao;

    @Autowired
    private CommodityMachineStockDataDao stockDataDao;

    @Autowired
    private UserHolderUtil userHolderUtil;

    @Autowired
    private EncryptUtil encryptUtil;

    @Autowired
    private OrderPickUpManager orderPickUpManager;

    @Override
    public int add(CommodityMachineEntity commodityMachineEntity) {
        commodityMachineEntity.setActivationCode(encryptUtil.MD5(ZhhStringUtil.normalGenerate()));
        commodityMachineEntity.setBaseCreateInfo(userHolderUtil.getCurrentUser().getId());
        return dao.insert(commodityMachineEntity);
    }

    @Override
    public int delete(String id) {
        CommodityMachineEntity commodityMachineEntity = dao.selectById(id);
        Assert.notNull(commodityMachineEntity, "该记录不存在或已被删除");
        commodityMachineEntity.setDataStatus(DataStatus.DELETED).setUpdateInfo(userHolderUtil.getCurrentUser().getId());
        return dao.updateById(commodityMachineEntity);
    }

    @Override
    public int update(CommodityMachineEntity commodityMachineEntity) {
        return dao.updateById(commodityMachineEntity);
    }

    @Override
    public CommodityMachineEntity get(String id) {
        CommodityMachineEntity machine = dao.selectOne(
                new QueryWrapper<CommodityMachineEntity>()
                        .eq("id", id)
                        .eq("data_status", DataStatus.ENABLE)
        );
        Assert.notNull(machine, "该机器记录不存在或已被删除");
        machine.setStocks(getAllMachineStocks(new MachineStockQueryDto(machine.getId())));
        return machine;
    }

    @Override
    public Page<CommodityMachineEntity> page(MachineQueryDto dto) {
        Page<CommodityMachineEntity> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        QueryWrapper<CommodityMachineEntity> query = new QueryWrapper<>();
        query.orderByDesc("record_time");
        query.eq("data_status", DataStatus.ENABLE);
        if (StrUtil.isNotBlank(dto.getName())) {
            query.like("machine_name", dto.getName());
        }
        if (StrUtil.isNotBlank(dto.getMachineId())) {
            query.eq("id", dto.getMachineId());
        }
        if (null != dto.getRunningState()) {
            query.eq("running_state", dto.getRunningState());
        }
        if (null != dto.getActivationStatus()) {
            query.eq("activation_status", dto.getActivationStatus());
        }
        return dao.selectPage(page, query);
    }

    @Override
    public int addStock(CommodityMachineStock commodityMachineStock) {
        CommodityMachineEntity commodityMachineEntity = dao.selectById(commodityMachineStock.getMachineId());
        Assert.notNull(commodityMachineEntity, "该机器信息不存在或已被删除");
        Integer totalStock = commodityMachineEntity.getTotalStock();
        // 判断这个机器里所有种类的商品库存上限总和是否超过售货机售卖商品数量的上限
        // 找出这个机器当前贩卖商品种类的数量上限
        QueryWrapper<CommodityMachineStock> query = new QueryWrapper<>();
        query.eq("machine_id", commodityMachineEntity.getId()).eq("data_status", DataStatus.ENABLE);
        List<CommodityMachineStock> commodityMachineStocks = stockDao.selectList(query);
        // 累加
        int sum = commodityMachineStocks.stream().mapToInt(CommodityMachineStock::getTotalLimit).sum();
        Assert.isFalse(totalStock < sum + commodityMachineStock.getTotalLimit(), "设定的商品上限超出售卖机总库存上限");
        commodityMachineStock.setBaseCreateInfo(userHolderUtil.getCurrentUser().getId());
        return stockDao.insert(commodityMachineStock);
    }

    @Override
    public int deleteStock(Integer stockId) {
        CommodityMachineStock commodityMachineStock = stockDao.selectById(stockId);
        Assert.notNull(commodityMachineStock, "该记录不存在或已被删除");
        commodityMachineStock.setDataStatus(DataStatus.DELETED)
                .setUpdateInfo(userHolderUtil.getCurrentUser().getId());
        return stockDao.updateById(commodityMachineStock);
    }

    @Override
    public int updateStock(CommodityMachineStock commodityMachineStock) {
        commodityMachineStock
                .setUpdateInfo(userHolderUtil.getCurrentUser().getId());
        return stockDao.updateById(commodityMachineStock);
    }

    @Override
    public CommodityMachineStock getStock(Integer stockId) {
        return stockDao.selectOne(
                new QueryWrapper<CommodityMachineStock>()
                        .eq("id", stockId)
                        .eq("data_status", DataStatus.ENABLE)
        );
    }

    @Override
    public List<CommodityMachineStockVo> getAllMachineStocks(MachineStockQueryDto dto) {
        return stockDao.listMachineStockInfo(dto);
    }

    @Override
    public Page<StockVo> machineStockPage(MachineQueryDto dto) {
        // page在此处的作用是传递total和record
        Page<StockVo> page = new Page<>();
        page.setTotal(stockDao.count(dto));
        page.setRecords(stockDao.pageStockVo(dto));
        return page;
    }

    @Transactional
    @Override
    public int deleteStocks(List<Integer> ids) {
        CommodityMachineStock updateDto = new CommodityMachineStock();
        updateDto.setUpdateInfo(userHolderUtil.getCurrentUser().getId(), new Date(), DataStatus.DELETED);
        int i = stockDao.update(updateDto, new QueryWrapper<CommodityMachineStock>().in("id", ids));
        int i1 = stockDao.deleteStockDataByStockIds(ids);
        return i + i1;
    }

    @Transactional
    @Override
    public int batchAddStock(List<CommodityMachineStock> stocks) {
        if (CollUtil.isEmpty(stocks)) {
            return 0;
        }
        Date now = new Date();
        String currentUserId = userHolderUtil.getCurrentUser().getId();
        List<CommodityMachineStockData> dataList = Lists.newArrayList();
        for (int i = 0; i < stocks.size(); i++) {
            CommodityMachineStock stock = stocks.get(i);
            stock.setBaseCreateInfo(currentUserId, now, DataStatus.ENABLE);
        }
        int result = stockDao.insertBatchSomeColumn(stocks);
        for (int i = 0; i < stocks.size(); i++) {
            CommodityMachineStock stock = stocks.get(i);
            CommodityMachineStockData data = new CommodityMachineStockData(stock.getId(), stock.getTotalLimit(), stock.getTotalLimit());
            dataList.add(data);
        }
        int result2 = stockDataDao.insertBatchSomeColumn(dataList);
        // 售货机容量上限通过前端进行限制，减轻服务器业务压力
        return result + result2;
    }

    @Transactional
    @Override
    public int batchDelete(List<String> ids) {
        String currentUserId = userHolderUtil.getCurrentUser().getId();
        CommodityMachineEntity update = new CommodityMachineEntity();
        update.setUpdateInfo(currentUserId, new Date(), DataStatus.DELETED);
        CommodityMachineStock stock = new CommodityMachineStock();
        stock.setDataStatus(DataStatus.DELETED);
        stockDao.update(stock, new QueryWrapper<CommodityMachineStock>().in("machine_id", ids));
        return dao.update(update, new QueryWrapper<CommodityMachineEntity>().in("id", ids));
    }

    @Override
    public List<StockDataVo> getStockDataVo(String machineId) {
        return stockDataDao.listStockDataVo(machineId);
    }

    @Override
    public Page<CommodityMachineEntity> statePage(MachineQueryDto dto) {
        Page<CommodityMachineEntity> page = page(dto);
        if (CollUtil.isEmpty(page.getRecords())) {
            return page;
        }
        List<CommodityMachineEntity> records = page.getRecords();
        for (int i = 0; i < records.size(); i++) {
            CommodityMachineEntity entity = records.get(i);
            entity.setQueueSize(orderPickUpManager.getQueueSize(entity.getId()));
        }
        return page;
    }

    @Override
    public List<MachineOptionsVo> machineToOptions() {
        return  dao.machineToOptions();
    }

}
